package com.game.message.selfbinary;

import com.game.message.transport.DataBuffer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 应答，发送数据
 *
 * @author Tony
 * @createAt Feb 18, 2015
 */
public class Message {
    private Logger logger = LoggerFactory.getLogger(Message.class);

    protected Header header;
    protected DataBuffer body;

    public Message(DataBuffer buffer) {
        decode(buffer);
    }

    public Message() {
    }

    public Header getHeader() {
        return header;
    }

    public void setHeader(Header header) {
        this.header = header;
    }

    public DataBuffer getBody() {
        return body;
    }

    public void setBody(DataBuffer data) {
        body = data;
    }

    /**
     * 写入对象
     *
     * @param body
     */
    public void writeBodyBuffer(DataBuffer body) {
        if (this.body == null) {
            this.body = new DataBuffer();
        }
        this.body.writeDataBuffer(body);
    }

    /**
     * 写入对象
     *
     * @param messageBean
     */
    public void writeMessageBean(MessageBean messageBean) {
        writeBodyBuffer(messageBean.toBodyBuffer());
    }


    /**
     * 读取对象
     *
     * @param entityClass
     * @param <T>
     * @return
     */
    public <T extends MessageBean> T readMessageBean(Class<T> entityClass) {
        try {
            T entity = entityClass.newInstance();
            readMessageBean(entity);
            return entity;
        } catch (Exception e) {
            logger.error("entity newInstance error!!!", e);
        }
        return null;
    }

    /**
     * 读取对象
     *
     * @param <T>
     * @param entity
     * @return
     */
    public <T extends MessageBean> T readMessageBean(T entity) {
        entity.fromBodyBuffer(body);
        return entity;
    }

    /**
     * Length | Header | Actual Content
     *
     * @param buffer
     */
    public void decode(DataBuffer buffer) {
        if (buffer != null) {
            try {
                // length
                int length = buffer.readInt();
                // header
                header = new Header();
                header.setLength(length);
                header.decode(buffer);
                // data
                body = buffer.readDataBuffer();
            } catch (Exception e) {
                logger.error(e.getMessage());
            }
        }
    }

    /**
     * 把header和body转成一个DataBuffer
     * Length | Header | Actual Content
     *
     * @return body
     */
    public DataBuffer encode() {
        try {
            DataBuffer buffer = new DataBuffer();
            // length
            int length = Header.PROTOCOL_HEADER_LENGTH;
            if (body != null) {
                length += body.readableBytes();
            }
            buffer.writeInt(length);
            // header
            header.setLength(length);
            buffer.writeDataBuffer(header.encode());
            // data
            buffer.writeDataBuffer(body);
            return buffer;
        } catch (Exception e) {
            logger.error("toBodyBuffer error!!!", e);
            throw new RuntimeException("toBodyBuffer error!!!");
        }
    }
}
